package cn.edu.java.thread.原子类;

import lombok.SneakyThrows;

import java.util.concurrent.atomic.AtomicStampedReference;

public class AtomicStampedReferenceDemo {
    private static AtomicStampedReference<String> atomicRef = new AtomicStampedReference<>("A", 0);

    @SneakyThrows
    public static void main(String[] args) {
        // 创建两个线程，分别进行引用值的修改
        Thread thread1 = new Thread(() -> {
            // 获取当前的引用值和标记值
            String currentRef = atomicRef.getReference();
            int currentStamp = atomicRef.getStamp();

            // 模拟引用值从 A 到 B 再到 A 的变化
            atomicRef.compareAndSet(currentRef, "B", currentStamp, currentStamp + 1);
            atomicRef.compareAndSet("B", "A", currentStamp + 1, currentStamp + 2);
        });

        Thread thread2 = new Thread(() -> {
            // 获取当前的引用值和标记值
            String currentRef = atomicRef.getReference();
            int currentStamp = atomicRef.getStamp();

            // 让线程2休眠一段时间，确保线程1先执行完
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 尝试将引用值从 A 更新为 C，期望标记值为当前标记值
            boolean success = atomicRef.compareAndSet(currentRef, "C", currentStamp, currentStamp + 1);
            System.out.println("Thread 2 update: " + success);
        });

        // 启动两个线程
        thread1.start();
        thread2.start();

        // 等待两个线程执行完毕
        thread1.join();
        thread2.join();

        // 输出最终的引用值和标记值
        System.out.println("Final reference: " + atomicRef.getReference());
        System.out.println("Final stamp: " + atomicRef.getStamp());
    }
}
